home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-05-03 | 34.1 KB | 1,090 lines | [TEXT/ALFA] |
- ## -*-Tcl-*-
- # # ###################################################################
- # Alpha - new Tcl folder configuration
- #
- # FILE: "tclMode.tcl"
- # created: 5/4/97 {9:31:10 pm}
- # last update: 05/03/1999 {18:39:51 PM}
- # Author: Vince Darley
- # E-mail: <darley@fas.harvard.edu>
- # mail: Division of Engineering and Applied Sciences, Harvard University
- # Oxford Street, Cambridge MA 02138, USA
- # www: <http://www.fas.harvard.edu/~darley/>
- #
- # Copyright (c) 1997-1999 Vince Darley
- #
- # Three procs from original: Tcl::DblClick listArray, getVarValue
- #
- # Adds support for Tk, Itcl keywords and completions, plus
- # numerous fixes, improvements and integration with Vince's
- # Additions.
- # ###################################################################
- ##
-
- alpha::mode Tcl 1.7.3 tclMenu {*.tcl *.itcl *.itk} {
- tclMenu electricTab electricReturn electricBraces
- } {
- addMenu tclMenu "•269" "Tcl"
- set unixMode(wish) {Tcl}
- set unixMode(tclsh) {Tcl}
- ensureset tclshSig "WIsH"
- ensureset evaluateRemotely 0
- trace variable evaluateRemotely w evaluateRemoteSynchronise
- } maintainer {
- "Vince Darley" darley@fas.harvard.edu <http://www.fas.harvard.edu/~darley/>
- } uninstall this-file help {
- This mode is for editing Tcl code. You can edit code for internal
- use with Alpha, or use Alpha as an external editor for code destined
- for use with Tcl and Tk interpreters --- Sun distributes the Wish
- application and a tcl-tk browser plugin.
-
- You can 'evaluate' a procedure (or any Tcl code for that matter) to
- make changes on the fly. If you select 'Evaluate Remotely' in the
- tcl-tk submenu, then such actions will actually send the code
- to a separately running Wish application to be evaluated.
- }
-
-
- proc tclMenu {} {}
-
- # ◊◊◊◊ menu and prefs ◊◊◊◊ #
- # The menu.
- proc menu::buildtclMenu {} {
- global tclMenu evaluateRemotely
- set ma [list \
- "/Levaluate" "/-<UswitchToTclsh" \
- [list Menu -n "tcl-tk" -p tcltk::menuProc [list \
- "![lindex {{ } •} $evaluateRemotely]evaluateRemotely" \
- executeCommand]] \
- "(-" "/L<O<BreloadProc" "/I<O<BreformatProc" \
- "/Z<O<BtraceThisProc" "/Z<O<UtraceTclProc…" \
- "/D<O<UdumpTraces" "(-" "rebuildTclIndices" "(-" \
- "<U/PfindProcDefinition…" "/Q<IquickFindProc…" "getVarValue…" \
- "insertMenuCodes…" "insertBindingCodes…" "/4<BaddRemoveDollars" \
- "/3<BinsertDivider" "/8<I<BsurroundWithBullets"]
- return [list build $ma Tcl::MenuProc "" $tclMenu]
- }
- menu::buildProc tclMenu menu::buildtclMenu
- menu::buildSome tclMenu
-
- newPref v prefixString {# } Tcl
- newPref f wordWrap {0} Tcl
- newPref v funcExpr {^proc *([+-a-zA-Z0-9]+)} Tcl
- newPref v parseExpr {^proc *([+-a-zA-Z0-9]+)} Tcl
- newPref v wordBreak {(\$)?[\w:_]+} Tcl
- newPref v wordBreakPreface {([^\w:_\$]|.\$)} Tcl
- newPref f autoMark 0 Tcl
- newPref v stringColor green Tcl
- newPref v commentColor red Tcl
- newPref v keywordColor blue Tcl
- # Colour to use for Alpha's built in commands
- newPref v alphaKeyWordColor none Tcl stringColorProc
- # Colour Tk commands
- newPref f recogniseTk 1 Tcl Tcl::_updateKeywords
- # Colour [incr Tcl] commands
- newPref f recogniseItcl 1 Tcl Tcl::_updateKeywords
- # Recognise and colour some common procedures 'lunion' etc.
- newPref f recognisePseudoTcl 1 Tcl Tcl::_updateKeywords
- # Indentation scheme for lines following one ending in a backslash
- newPref v indentSlashEndLines 1 Tcl "" indent::amounts varindex
- # Mark files structurally, recognising the special comments
- # entered by 'ctrl-3'
- newPref f structuralMarks 0 Tcl
- set Tcl::startPara {^(.*\{)?[ \t]*(#|$)}
- set Tcl::endPara {^(.*\})?[ \t]*(#|$)}
- set Tcl::commentRegexp {^[ \t]*#}
-
- ##
- # -------------------------------------------------------------------------
- #
- # "Tcl::_updateKeywords" --
- #
- # This proc now includes support for optional separate colorization of
- # alpha commands. To use, set 'alphaKeyWordColor' to something other than
- # 'none' in the Tcl Mode Preferences dialog. -trf
- # -------------------------------------------------------------------------
- ##
- proc Tcl::_updateKeywords {args} {
- set tclKeyWords {
- after append array auto_execok auto_load auto_mkindex
- auto_reset beep binary break case catch cd clock close concat
- continue echo eof error eval exit expr fblocked fconfigure
- fcopy file fileevent flush for foreach format gets glob global
- history if incr info interp join lappend lindex linsert list
- llength load lrange lreplace ls lsearch lsort namespace open
- package pid pkg_mkIndex proc puts pwd read regexp regsub
- rename resource return scan seek set socket source split
- string subst switch tclMacPkgSearch tclPkgSetup tclPkgUnknown
- tell time trace unknown unset update uplevel upvar variable
- vwait while scancontext else elseif default
- }
-
- set alphaKeyWords {
- abortEm abbrev addAlphaChars addMenuItem addDef addArrDef
- AEBuild alertnote alphaHelp ascii askyesno backColor backSpace
- backwardChar backwardCharSelect backwardDeleteWord
- backwardWord balance beginningBufferSelect beginningLineSelect
- beginningOfBuffer beginningOfLine Bind blink breakIntoLines
- bringToFront buttonAlert capitalizeRegion capitalizeWord
- centerRedraw clear closeAll colors colorTriple copy cp
- createTagFile createTMark currentPosition cut decToHex
- deleteChar deleteMenuItem deleteModeBindings deleteSelection
- deleteWord describeBinding deleteText dialog dirs display
- displayMode dosc downcaseRegion downcaseWord dumpColors
- dumpMacro edit enableMenuItem endBufferSelect endKeyboardMacro
- endLineSelect endOfBuffer endOfLine enterSelection evaluate
- eventHandler exchangePointAndMark execAbbrev execute
- executeKeyboardMacro fileInfo fileRemove find findAgain
- findAgainBackward findFile findInNextFile findTag float
- floatShowHide forwardChar forwardCharSelect forwardWord
- freeMem get_directory getAscii getChar getModifiers getColors
- getfile getFileInfo getGeometry getline getMainDevice getMark
- getNamedMarks getPathName getPos getScrap getSelect getText
- getTMarks getWinInfo goto gotoMark gotoTMark hexToDec icon
- icURL icGetPref icOpen insertAscii insertColorEscape
- insertFile insertMenu insertPathName insertText insertToTop
- isearch iterationCount jumpToRegister keyAscii keyCode
- killLine killWindow largestPrefix launch lineStart
- listBindings listpick lookAt markHilite markMenuItem
- matchBrace matchIt maxPos Menu message mkdir mousePos
- moveInsertionHere moveFile moveWin mtime nameFromAppl new
- nextLine nextLineSelect nextLineStart nextSentence nextWindow
- now oneSpace openLine otherPane pageBack pageForward pageSetup
- paste pointToRegister popd posToRowCol prefixChar previousLine
- prevLineSelect prevSentence prevWindow print processes prompt
- pushd putfile putScrap quit rectMarkHilite redo
- regModeKeywords removeArrDef removeDef removeFile removeMark
- removeMenu removeTMark replace replaceAll replace&FindAgain
- replaceString replaceText restoreVars revert rmdir rowColToPos
- rsearch save saveAs saveVars scrollDownLine scrollLeftCol
- scrollRightCol scrollUpLine search searchString select selEnd
- sendOpenEvent sendToBack setFileInfo setFontsTabs setMark
- setNamedMark setWinInfo shell shiftLeftRegion shiftRightRegion
- sizeWin sortMarks spacesToTabs specToPathName splitWindow
- startEscape startKeyboardMacro statusPrompt substituteVars
- switchTo tab tabsToSpaces tclFileCompletion tclResult
- thinkReference ticks toggleScrollbar traceFunc unascii unBind
- undo unfloat upcaseRegion upcaseWord version watchCursor wc
- winNames wrap wrapText xtclcmd yank zapInvisibles zoom
- }
-
- set tkKeyWords {
- bind bindtags button canvas checkbutton console destroy entry event focus
- font frame grab grid image menubutton pack place radiobutton raise
- scale scrollbar text tk tkwait toplevel winfo wm label listbox
- menu
- }
-
- set itclKeyWords {
- @scope body class code common component configbody constructor define
- destructor hull
- import inherit itcl itk itk_component itk_initialize itk_interior
- itk_option iwidgets keep method private protected
- public
- }
- global TclmodeVars
- # add Tk keywords
- if {$TclmodeVars(recogniseTk)} {
- set tclKeyWords [concat $tclKeyWords $tkKeyWords]
- }
- # add the [incr tcl] keywords
- if {$TclmodeVars(recogniseItcl)} {
- set tclKeyWords [concat $tclKeyWords $itclKeyWords]
- }
- if {$TclmodeVars(recognisePseudoTcl)} {
- set tclKeyWords [concat $tclKeyWords "lunion lreverse lremove lunique car"]
- }
- # add user extras
- global Tclwords
- if {[info exists Tclwords]} {
- set tclKeyWords [concat $tclKeyWords $Tclwords]
- }
- global Tclcmds
- set Tclcmds { append array catch close concat continue elseif error
- for foreach format lindex llength lrange lreplace lsearch lsort regexp
- regsub rename return string switch while }
- if {$TclmodeVars(recogniseTk)} {
- append Tclcmds {
- tkButtonDown tkButtonEnter tkButtonInvoke tkButtonLeave
- tkButtonUp tkCancelRepeat tkCheckRadioInvoke tkDarken
- tkEntryAutoScan tkEntryBackspace tkEntryButton1
- tkEntryClosestGap tkEntryInsert tkEntryKeySelect
- tkEntryMouseSelect tkEntryNextWord tkEntryPaste
- tkEntryPreviousWord tkEntrySeeInsert tkEntrySetCursor
- tkEntryTranspose tkEventMotifBindings tkFDGetFileTypes
- tkFirstMenu tkFocusGroup_BindIn tkFocusGroup_BindOut
- tkFocusGroup_Create tkFocusGroup_Destroy tkFocusGroup_In
- tkFocusGroup_Out tkFocusOK tkListboxAutoScan
- tkListboxBeginExtend tkListboxBeginSelect tkListboxBeginToggle
- tkListboxCancel tkListboxDataExtend tkListboxExtendUpDown
- tkListboxMotion tkListboxSelectAll tkListboxUpDown tkMbButtonUp
- tkMbEnter tkMbLeave tkMbMotion tkMbPost tkMenuButtonDown
- tkMenuDownArrow tkMenuDup tkMenuEscape tkMenuFind
- tkMenuFindName tkMenuFirstEntry tkMenuInvoke tkMenuLeave
- tkMenuLeftArrow tkMenuMotion tkMenuNextEntry tkMenuNextMenu
- tkMenuRightArrow tkMenuUnpost tkMenuUpArrow tkMessageBox
- tkPostOverPoint tkRecolorTree tkRestoreOldGrab tkSaveGrabInfo
- tkScaleActivate tkScaleButton2Down tkScaleButtonDown
- tkScaleControlPress tkScaleDrag tkScaleEndDrag tkScaleIncrement
- tkScreenChanged tkScrollButton2Down tkScrollButtonDown
- tkScrollButtonUp tkScrollByPages tkScrollByUnits tkScrollDrag
- tkScrollEndDrag tkScrollSelect tkScrollStartDrag tkScrollToPos
- tkScrollTopBottom tkTabToWindow tkTearOffMenu tkTextAutoScan
- tkTextButton1 tkTextClosestGap tkTextInsert tkTextKeyExtend
- tkTextKeySelect tkTextNextPara tkTextNextPos tkTextNextWord
- tkTextPaste tkTextPrevPara tkTextPrevPos tkTextResetAnchor
- tkTextScrollPages tkTextSelectTo tkTextSetCursor
- tkTextTranspose tkTextUpDownLine tkTraverseToMenu
- tkTraverseWithinMenu tk_bisque tk_chooseColor tk_dialog
- tk_focusFollowsMouse tk_focusNext tk_focusPrev tk_getOpenFile
- tk_getSaveFile tk_messageBox tk_optionMenu tk_popup
- tk_setPalette tk_textCopy tk_textCut tk_textPaste
- }
- }
-
- if {$TclmodeVars(recogniseTk)} {
- regModeKeywords -e {#} -c $TclmodeVars(commentColor) \
- -s $TclmodeVars(stringColor) \
- -k $TclmodeVars(keywordColor) Tcl $tclKeyWords
- # add this line if we can handle double 'magic chars'
- #-m {tk}
- } else {
- regModeKeywords -e {#} -c $TclmodeVars(commentColor) \
- -s $TclmodeVars(stringColor) \
- -k $TclmodeVars(keywordColor) Tcl $tclKeyWords
- }
- if {$TclmodeVars(alphaKeyWordColor) != "none"} {
- regModeKeywords -a -k $TclmodeVars(alphaKeyWordColor) Tcl $alphaKeyWords
- }
- }
- # call it now
- Tcl::_updateKeywords
-
- proc Tcl::MenuProc {menu item} {
- switch -glob $item {
- "traceThisProc" {
- procs::traceProc [procs::findEnclosingName [getPos]]
- }
- "reformatProc" {
- procs::reformatEnclosing [getPos]
- }
- "reloadProc" {
- procs::loadEnclosing [getPos]
- }
- "findProcDefinition" {
- procs::findDefinition
- }
- "quickFindProc" {
- # use the status line
- procs::quickFindDefn
- }
- "switch*" {
- set v "[string tolower [string range $item 8 end]]Sig"
- global $v
- app::launchFore [set $v]
- }
- "addRemoveDollars" {
- togglePrefix \$
- }
- default {
- uplevel \#0 $item
- }
- }
- }
- namespace eval tcltk {}
-
- proc tcltk::menuProc {menu item} {
- switch -- $item {
- "evaluateRemotely" {
- global evaluateRemotely
- set evaluateRemotely [expr {1 - $evaluateRemotely}]
- }
- default {
- global tclshSig
- set cmd [getline "Please enter the script to send to tcl-tk"]
- if {$cmd == ""} {return}
- if {$tcl_platform(platform) == "macintosh"} {
- set res [AEBuild -r -t 30000 '$tclshSig' misc dosc ---- "“$cmd”"]
- } else {
- set res [tcltk::evaluate $cmd]
- }
- alertnote "Result was '$res'"
- }
- }
- }
-
- proc evaluateRemoteSynchronise {args} {
- global evaluateRemotely tclMenu
- catch {markMenuItem "tcl-tk" evaluateRemotely $evaluateRemotely}
- if {$evaluateRemotely} {
- if {[info commands notRemoteEvaluate] == ""} {
- rename evaluate notRemoteEvaluate
- ;proc evaluate {} {remoteEvaluate}
- }
- menu::replaceRebuild tclMenu "•320"
- } else {
- if {[info commands notRemoteEvaluate] != ""} {
- rename evaluate {}
- rename notRemoteEvaluate evaluate
- }
- menu::replaceRebuild tclMenu "•269"
- }
- }
-
-
- proc remoteEvaluate {} {
- message "Remote reply: [tcltk::evaluate [getSelect]]"
- }
-
- proc tcltk::evaluate {what} {
- global tclshSig tcl_platform
- if {$tcl_platform(platform) == "macintosh"} {
- app::ensureRunning $tclshSig
- set r [AEBuild -r -t 30000 '${tclshSig}' misc dosc ---- "“$what”"]
- set r [lindex [aeparse::event $r] 2]
- if {[lindex [lindex $r 0] 0] == "errs"} {
- set res "Error: "
- }
- append res [aeparse::TEXT [aeparse::keywordValue [lindex $r 0] $r]]
- #catch {dosc -c '${tclshSig}' -s $what} res
- } else {
- global tclshInterp
- if {![info exists tclshInterp]} {
- if {[catch {tcltk::findTclshInterp}]} {
- return "No shell selected"
- }
- }
- if {$tcl_platform(platform) == "windows"} {
- if {[dde services Tk $tclshInterp] == ""} {
- alertnote "The remove shell has died, please select a new one."
- unset tclshInterp
- return [tcltk::evaluate $what]
- }
- catch {dde execute Tk $tclshInterp $what} res
- } else {
- catch {send $tclshInterp $what} res
- }
- }
- return $res
- }
-
- proc tcltk::findTclshInterp {} {
- global tclshInterp tclshSigs tclshSig
- set shel [listpick -p "Use which Tcl shell?" [concat [winfo interps] \
- [list "------------------" "Launch new shell"]]]
- if {$shel == "Launch new shell"} {
- set old [winfo interps]
- app::launchElseTryThese $tclshSigs tclshSig "Please locate the remote Tcl application"
- launch -f $tclshSig
- while {[winfo interps] == $old} {
- update
- }
- set tclshInterp [lremove -l [winfo interps] $old]
- # We're left with two items
- set tclshInterp [lindex $tclshInterp 0]
- } else {
- set tclshInterp $shel
- }
- }
-
- # ◊◊◊◊ Quick Find Proc… ◊◊◊◊ #
-
- proc procs::quickFindDefn {} {
- Tcl::DblClickHelper [prompt::statusLineComplete "proc" procs::complete]
- }
-
- if {[info tclversion] < 8.0} {
- proc procs::complete {pref} {
- return [info commands ${pref}*]
- }
- } else {
- proc procs::complete {pref} {
- if {[regexp {(.*)([^:]+)$} $pref "" start tail]} {
- set cmds [info commands ${pref}*]
- foreach child [namespace children ::$start] {
- if {[string match "::${tail}*" $child]} {
- foreach cmd [info commands ${start}${child}::*] {
- lappend cmds [string trimleft $cmd :]
- }
- }
- }
- return $cmds
- } else {
- return [info commands ${pref}*]
- }
- }
- }
-
- # ◊◊◊◊ electric behaviour ◊◊◊◊ #
- proc Tcl::electricLeft {} {
- if {[literalChar]} { insertText "\{"; return }
- set pat "\}\[ \t\r\n\]*(else(if)?)\[ \t\r\n\]*\$"
- set p [getPos]
- if { [set res [findPatJustBefore "\}" "$pat" $p word]] == "" } {
- insertText "\{"
- return
- }
- # we have an if/else(if)/else
- switch -- $word {
- "else" {
- replaceText [lindex $res 0] $p "\} $word \{\r"
- bind::IndentLine
- }
- "elseif" {
- replaceText [lindex $res 0] $p "\} $word \{"
- }
- }
- }
-
- proc Tcl::electricRight {} {
- if {[literalChar]} { insertText "\}"; return }
- set p [getPos]
- if { [regexp "\[^ \t\]" [getText [lineStart $p] $p]] } {
- insertText "\}"
- blink [matchIt "\}" [pos::math $p - 1]]
- return
- }
- set start [lineStart $p]
- insertText "\}"
- createTMark tcl_er [getPos]
- backwardChar
- bind::IndentLine
- gotoTMark tcl_er ; removeTMark tcl_er
- bind::CarriageReturn
- blink [matchIt "\}" [pos::math $start - 1]]
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "Tcl::correctIndentation" --
- #
- # Returns the correct indentation for the line containing $pos, if that
- # line were to contain ordinary characters only. It is the
- # responsibility of the calling procedure to ensure that if we are to
- # insert/have a line already, that that information is taken into
- # account, by passing in the argument 'next'
- # -------------------------------------------------------------------------
- ##
- proc Tcl::correctIndentation {pos {next ""}} {
- global indent_amounts indentSlashEndLines
- # preliminaries
- if {[pos::compare [set beg [lineStart $pos]] == [minPos]]} { return 0 }
- # if the current line is a comment, we have to check some
- # special cases
- if {[string index $next 0] == "\#"} {
- set p [prevLineStart $beg]
- if {[catch {set p [search -s -f 0 -r 1 -i 0 -m 0 "^\[ \t\]*\[^ \t\r\n\]" \
- [pos::math $beg - 1]]}]} {
- # check for search bug at beginning of file.
- if {[pos::compare $p == [minPos]]} {
- if {[getText [minPos] [pos::math [minPos] + 2]] == "\#\#"} {
- if {([string range $next 0 1] != "\#\#")} {
- return 1
- } else {
- return 0
- }
- }
- }
- return 0
- }
- set prev [pos::math [lindex $p 1] - 1]
- set p [lindex $p 0]
- if {[lookAt $prev] != "\#" || ($beg == [minPos])} {
- # not a comment, so indent with code
- } else {
- set lwhite [posX $prev]
- # it's a comment
- if {[getText $prev [pos::math $prev + 2]] == "\#\#" && \
- [lookAt [pos::math $prev + 2]] != "\#" \
- && ([string range $next 0 1] != "\#\#")} {
- # it's a comment paragraph
- incr lwhite
- }
- }
- }
- set next [string index $next 0]
- if {![info exists lwhite]} {
- if {![catch {search -s -f 0 -r 1 -i 0 -m 0 "^\[ \t\]*\[^\# \t\r\n\]" [pos::math $beg - 1]} lst]} {
- # Find the last non-comment line and get its leading whitespace
- set lwhite [posX [pos::math [lindex $lst 1] - 1]]
- set pe1 [lookAt [pos::math $beg - 2]]
- set lst [lindex $lst 0]
- set lastC [lookAt [lindex [search -s -f 0 -r 1 -i 0 -m 0 "\[^ \t\r\n\]" [pos::math [nextLineStart $lst] - 1]] 0]]
- if {$next == "\}"} {
- incr lwhite $indent_amounts(-2)
- set pe2 [lookAt [pos::math [prevLineStart $beg] - 2]]
- if {$pe1 == "\\"} {
- incr lwhite $indent_amounts(1)
- } else {
- if {$pe2 == "\\"} {
- incr lwhite $indent_amounts(-1)
- }
- }
- if {$lastC == "\{"} {incr lwhite $indent_amounts(2)}
- } else {
- if {$pe1 == "\\"} {
- if {[lookAt [pos::math [prevLineStart $beg] - 2]] != "\\"} {
- incr lwhite $indent_amounts($indentSlashEndLines)
- }
- } else {
- if {$lastC == "\{"} {incr lwhite $indent_amounts(2)}
- if {[lookAt [pos::math $lst - 2]] == "\\"} {
- incr lwhite $indent_amounts(-$indentSlashEndLines)
- }
- }
- }
- } else {
- # basically failed in all the above, so keep current indentation
- set lwhite [posX [text::firstNonWsLinePos $beg]]
- }
- }
- return [expr {$lwhite > 0 ? $lwhite : 0}]
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "Tcl::indentLine" --
- #
- # Indentation for Tcl mode. Better and faster than the generic procedure
- # -------------------------------------------------------------------------
- ##
- proc Tcl::indentLine {} {
- set beg [lineStart [getPos]]
- set text [getText $beg [nextLineStart $beg]]
- regexp "^\[ \t\]*" $text white
- set next [pos::math $beg + [string length $white]]
- set lwhite [Tcl::correctIndentation [getPos] [getText $next [pos::math $next + 2]]]
-
- set lwhite [text::indentOf $lwhite]
- if {$white != $lwhite} {
- replaceText $beg $next $lwhite
- }
- goto [pos::math $beg + [string length $lwhite]]
- }
- # ◊◊◊◊ Tcl Menu support ◊◊◊◊ #
-
- proc procs::reformatEnclosing {pos} {
- set p [procs::findEnclosing $pos "proc|body|configbody" 1]
- eval select $p
- ::indentRegion
- }
-
- proc procs::loadEnclosing {pos} {
- if {[catch {procs::findEnclosing $pos "proc|body|configbody" 1} p]} {
- evaluateLine $pos
- } else {
- eval select $p
- uplevel \#0 evaluate
- }
- goto $pos
- }
-
- proc procs::findDefinition {} {
- if {[llength [winNames]] && [string length [set sel [getSelect]]]} {
- set func [listpick -L $sel -p {Proc?} [lsort -ignore [info procs]]]
- } else {
- set func [listpick -p {Proc?} [lsort -ignore [info procs]]]
- }
-
- editMark [procs::find $func] $func
- }
-
- proc insertMenuCodes {} {
- insertText [prompt::getAKey]
- }
-
- proc insertBindingCodes {} {
- beep
- keyCode
- }
-
-
- ##
- # -------------------------------------------------------------------------
- #
- # "insertDivider" --
- #
- # Modified from Vince's original to allow you to just select part of
- # an already written comment and turn it into a Divider. -trf
- # -------------------------------------------------------------------------
- ##
- proc insertDivider {} {
- if {[isSelection]} {
- set enfoldThis [getSelect]
- beginningOfLine
- killLine
- insertText "# ◊◊◊◊ $enfoldThis ◊◊◊◊ #"
- return
- }
- elec::Insertion "# ◊◊◊◊ •• ◊◊◊◊ #"
- }
-
- # vince's versions seems to have been left out, so here's mine -trf
- # If there is a selection, it get surrounded, if there is no selection,
- # but the cursor is touching the end of a word, it gets surrounded.
- # Otherwise, we get a template (could not come up with a "stop beyond")
- proc surroundWithBullets {} {
- if {[pos::compare [getPos] == [selEnd]]} {
- set p [getPos]
- backwardWord
- set sw [getPos]
- forwardWord
- set ew [getPos]
- goto $p
- if {[pos::compare $p == $ew]} {
- select $sw $ew
- }
- }
- if {[isSelection]} {
- set enfoldThis [getSelect]
- deleteSelection
- insertText "•$enfoldThis•"
- return
- }
- insertText "••"
- backwardChar
- elec::Insertion "•replace-this•"
- }
- # ◊◊◊◊ Info providers ◊◊◊◊ #
- #===============================================================================
-
- ##
- # -------------------------------------------------------------------------
- #
- # "TclOptionTitlebar" --
- #
- # Add corresponding extension/non-extension files.
- # -------------------------------------------------------------------------
- ##
- proc Tcl::OptionTitlebar {} {
- if {[package::active smarterSource]} {
- set n [win::CurrentTail]
- if {[set a [string first + $n]] != -1} {
- return "[string range $n 0 [expr {$a -1}]][file extension $n]"
- } else {
- global tclExtensionsFolder
- pushd $tclExtensionsFolder
- set f [glob -nocomplain "[file root $n]+*[file extension $n]"]
- popd
- return $f
- }
- } else {
- return ""
- }
- }
-
- proc Tcl::DblClick {from to shift option control} {
-
- # if cmd and cntrl were pressed, we look to select part of
- # a combination word (less any leading dollar sign) -trf
- if {$control != 0} {
- set clickedPos [getPos]
- if {[lookAt $from] == "\$"} {
- set from [pos::math $from + 1]
- }
- set sel_start $clickedPos
- set selStartNotDetermined 1
- while {$selStartNotDetermined && ([pos::math $sel_start > $from])} {
- set char [lookAt $sel_start]
- if {[regexp {_} $char]} {
- set sel_start [pos::math $sel_start + 1]
- set selStartNotDetermined 0
- } elseif {[regexp {[A-Z]} $char]} {
- set selStartNotDetermined 0
- } else {
- set sel_start [pos::math $sel_start -1]
- }
- }
- set sel_end $clickedPos
- set selEndNotDetermined 1
- while {$selEndNotDetermined && ([pos::math $sel_end <= $to])} {
- set char [lookAt $sel_end]
- if {[regexp "\[A-Z_ \t\r\]" $char]} {
- set selEndNotDetermined 0
- } else {
- set sel_end [pos::math $sel_end + 1]
- }
- }
- select $sel_start $sel_end
- return
- }
-
- # otherwise, we try to impart some extra info
- select $from $to
-
- if {[catch {Tcl::DblClickHelper [getSelect]}]} {
- message "No docs $shift $control $option"
- }
- }
-
-
- # Now finds commands in Alpha Commands,
- # which has a <cr> immediately after them, e.g. beep, ticks.
- proc Tcl::DblClickHelper {text} {
- global HOME auto_index auto_path
- # Is it a loadable proc?
- if {[string length [set f [procs::find $text]]]} {
- if {[editMark $f $text]} {
- # some marking schemes commonly used for Tcl modes
- goto [lindex [search -s -f 1 -r 1 -m 0 -- "proc\[ \t\]+${text}" [minPos]] 0]
- }
- return
- }
-
- if {[info exists "auto_index($text)"]} {
- if {[editMark "$auto_index($text)" $text]} {
- # some marking schemes commonly used for Tcl modes
- goto [lindex [search -s -f 1 -r 1 -m 0 -- "proc\[ \t\]+${text}" [minPos]] 0]
- }
- return
- }
- # Is it a built-in Alpha command?
- set lines [grep "^• $text\( |\$)" [file join $HOME Help "Alpha Commands"]]
- if {[string length $lines]} {
- if {[catch {editMark [file join $HOME Help "Alpha Commands"] $text}]} {
- # mark failed for some reason, but we have the line number
- # anyway.
- file::openQuietly [file join $HOME Help "Alpha Commands"]
- goto [rowColToPos [string trimright [lindex [lindex [split $lines "\n"] 1] 3] :] 0]
- }
- setWinInfo read-only 1
- return
- }
- # Is it a core Tcl command?
- set lines [grep "^ $text -" [file join $HOME Help "Tcl Commands"]]
- if {[string length $lines]} {
- if {[catch {editMark [file join $HOME Help "Tcl Commands"] $text}]} {
- # mark failed for some reason, but we have the line number
- # anyway.
- file::openQuietly [file join $HOME Help "Tcl Commands"]
- goto [rowColToPos [string trimright [lindex [lindex [split $lines "\n"] 1] 3] :] 0]
- }
- setWinInfo read-only 1
- return
- }
- # Is it a global variable?
- if {[llength [info globals [string trimleft $text {$}]]]==1} {
- showVarValue [string trimleft $text {$}]
- return
- }
- # (becoming desperate) is it a mark in the current file?
- if {[lsearch [getNamedMarks -n] ${text}] != -1} {
- gotoMark $text
- return
- }
- error ""
- }
-
- #############################################################################
- # Report the current value of a global variable, chosen interactively
- # from a list of all active variables.
- #
- # If the variable is an array, or its value is too big to fit in an
- # alertnote, then its contents are listed in a new window, otherwise
- # the variable's value is displayed in an alertnote.
- #
- proc getVarValue {} {
- set def [getText [getPos] [selEnd]]
- set var [getVarFromList $def]
- if {[string length $var] == 0} return
- showVarValue $var
- }
-
- if {[info tclversion] < 8.0} {
-
- proc getVarFromList {{def ""}} {
- return [listpick -p {Which var?} -L $def [lsort -ignore [info globals]]]
- }
-
- } else {
-
- proc getVarFromList {{def ""}} {
- set ns "[namespace qualifiers $def]"
- set def [namespace tail $def]
-
- set items {}
- foreach var [info vars "${ns}::*"] {
- lappend items [namespace tail $var]
- }
- foreach space [namespace children $ns] {
- lappend items "[namespace tail $space]::"
- }
-
- set items [concat "::" [lsort -ignore $items]]
- set var [listpick -p "Which var in namespace ${ns}::?" -L $def $items]
- if {$var == "::"} {
- set var [getVarFromList $ns]
- } elseif {[namespace qualifiers $var] != ""} {
- set var [getVarFromList "${ns}::${var}"]
- } else {
- set var "${ns}::${var}"
- }
- return $var
- }
- }
-
- #############################################################################
- # Report the current value of a global variable, chosen interactively
- # from a list of all active variables.
- #
- # If the variable is an array, or its value is too big to fit in an
- # alertnote, then its contents are listed in a new window, otherwise
- # the variable's value is displayed in an alertnote.
- #
- proc showVarValue {var} {
- global $var
- if {![array exists $var]} {
- viewValue $var [set $var]
- } else {
- new -n "* $var *" -info [listArray $var]
- # if 'shrinkWindow' is loaded, call it to trim the output window.
- catch {shrinkWindow 2}
- }
- }
-
- #############################################################################
- # List the name and value of each element of the array $arrName.
- # (Convenient to use as a shell command.)
- #
- proc listArray {arrName} {
- global $arrName
- if {[array exists $arrName]} {
- set lines {}
- foreach nm [array names $arrName] {
- lappend lines "\"$nm\"\t\{[set ${arrName}($nm)]\}"
- }
- return [join $lines \r]
- } else {
- alertnote "\"$arrName\" doesn't exist in this context"
- }
- }
-
- # ◊◊◊◊ Marking ◊◊◊◊ #
-
- ##
- # -------------------------------------------------------------------------
- #
- # "Tcl::parseFuncs" --
- #
- # This proc is called by the "braces" pop-up. It returns a dynamically
- # created, alphabetical, list of "pseudo-marks".
- #
- # Author: Tom Fetherston
- # -------------------------------------------------------------------------
- ## called by the "{}" button
- proc Tcl::parseFuncs {} {
- global TclmodeVars
- set end [maxPos]
- set pos [minPos]
- set l {}
- set markExpr "^\[ \t\]*((itcl(::|_))?class|body|proc|method|body)\[ \t\]"
- set appearanceList {}
- while {![catch {search -s -f 1 -r 1 -m 0 -i 0 "$markExpr" $pos} res]} {
- set start [lindex $res 0]
- set end [nextLineStart $start]
- set t [getText $start $end]
- append t "\}"
- set argLabel {}
- switch -- [lindex $t 0] {
- "proc" {
- append argLabel [set word [lindex $t 1]]
- #get the list of arguments
- set argsList [lindex $t 2]
- if {[llength $argsList] > 0} {
- append argLabel " \{"
- foreach arg $argsList {
- if {[llength $arg] == 2 } {
- append argLabel "¿"
- } elseif {[set arg] != "args"} {
- append argLabel "•"
- } else {
- append argLabel "…"
- }
- }
- append argLabel "\}"
- }
- }
- default {
- append argLabel [set word [lindex $t 1]]
- }
- }
- if {[info exists cnts($word)]} {
- # This section handles duplicate. i.e., overloaded names
- set cnts($word) [expr {$cnts($word) + 1}]
- set tailOfTag($word) " ($cnts($word) of $cnts($word))"
- # we want the tag to point to its last occurence
- # because in Tcl, that proc will be 'in-force' when the
- # file is loaded.
- set indx($word) [lineStart [pos::math $start - 1]]
- } else {
- #SO do: remember the following
- set cnts($word) 1
- # if this is the only occurence of this proc, remember where it starts
- set indx($word) [lineStart [pos::math $start - 1]]
- }
- #associate name and tag
- set tag($word) $argLabel
-
- #advance pos to where we want to start the next search from
- set pos $end
- }
-
- set rtnRes {}
-
- if {[info exists indx]} {
- foreach hn [lsort -ignore [array names indx]] {
- set next [nextLineStart $indx($hn)]
- set completeTag [set tag($hn)]
- if {[info exists tailOfTag($hn)]} {
- append completeTag [set tailOfTag($hn)]
- }
-
- lappend rtnRes $completeTag $next
- }
- }
- return $rtnRes
- }
-
- # called by the "M" button
- proc Tcl::MarkFile {} {
- global structuralMarks
- set end [maxPos]
- set pos [minPos]
- set l {}
- if {$structuralMarks} {
- set markExpr {^;?[ ]*((itcl(::|_))?class|namespace eval|proc|method|(config)?body|# ◊◊◊◊)[ ]}
- } else {
- set markExpr {^;?[ ]*((itcl(::|_))?class|namespace eval|proc|method|(config)?body)[ ]}
- }
- set class ""
- set hasMarkers 0
- while {![catch {search -s -f 1 -r 1 -m 0 -i 0 "$markExpr" $pos} res]} {
- set start [lindex $res 0]
- set end [nextLineStart $start]
- set t [string trim [getText $start $end] ";"]
- append t "\}"
- if {[catch {lindex $t 0}]} {
- # wasn't a well formed list
- set pos $end
- continue
- }
- switch -glob [lindex $t 0] {
- "proc" -
- "configbody" { set text [lindex $t 1] }
- "method" { set text ${class}::[lindex $t 1] }
- "body" {
- regexp {[a-zA-Z_][a-zA-Z_/0-9]*::[a-zA-Z_][a-zA-Z_/0-9]* } \
- "[lindex $t 1] " text
- }
- "namespace" {
- set ns [lindex $t 2]
- set text "${ns} 111"
- }
- "*class" {
- set class [lindex $t 1]
- set text "${class} 000"
- }
- "#" {
- regexp "# ◊◊◊◊ (.*) ◊◊◊◊" $t all text
- if {[regexp "^( )|( )# ◊◊◊◊ " $t]} {
- set text " •$text"
- } else {
- set text "•$text"
- }
- set hasMarkers 1
- }
- }
- set pos $end
- if {$structuralMarks} {
- lappend asEncountered $text
- set arr inds
- } else {
- if {[string index $t 0] == ";"} {
- set arr iinds
- } else {
- set arr inds
- }
- }
- set ${arr}($text) [lineStart [pos::math $start - 1]]
- }
-
- set already ""
- set class "#"
- foreach arr {inds iinds} {
- if {[info exists $arr]} {
- if {$arr == "iinds"} {
- setNamedMark "-" 0 0 0
- }
- if {$structuralMarks} {
- set order $asEncountered
- } else {
- set order [lsort -ignore [array names $arr]]
- }
- foreach f $order {
- if {[set el [set ${arr}($f)]] != 0} {
- set next [nextLineStart $el]
- } else {
- set next 0
- }
-
- if { [string first "000" $f] != -1 } {
- set ff "Class '[set class [lindex $f 0]]'"
- } elseif { [string first "111" $f] != -1 } {
- set ff "Namespace '[set class [lindex $f 0]]'"
- } elseif { [string first "${class}::" $f] == 0 } {
- set ff [string range $f [string length $class] end]
- } else {
- set ff $f
- }
- while { [lsearch -exact $already $ff] != -1 } {
- set ff "$ff "
- }
- lappend already $ff
- if {$hasMarkers && ![string match "•*" $ff] } {
- set ff " $ff"
- }
- setNamedMark $ff $el $next $next
- }
- }
- }
- }
-
- # ◊◊◊◊ Misc. ◊◊◊◊ #
-
- ##
- # -------------------------------------------------------------------------
- #
- # "bind::tclContinueComment" --
- #
- # exploits a "feature" in the code that makes a new line a comment whenever
- # you are 'inside' a comment. This proc puts a pound sign at the end of the
- # current line, backsteps, and creates a new line. With the pound sign
- # present you are considered to be in a comment, so the bind::CarriageReturn
- # in the proc, and any subsequent bind::CarriageReturn called by a press of
- # the return key will provide another comment line automatically until the
- # pound sign at the end of the line is removed (killLine is handy for this).
- # -------------------------------------------------------------------------
- ##
- proc bind::tclContinueComment {} {
- insertText {#}
- backwardChar
- bind::CarriageReturn
- deleteChar
- }
- Bind '\r' <c> bind::tclContinueComment Tcl
-
- proc evaluateLine { pos } {
- goto $pos
- beginningLineSelect
- endLineSelect
-
- uplevel \#0 evaluate
- }
-
- #◊◊◊◊>
-
- evaluateRemoteSynchronise
-
-